<template>
  <el-card class="box-card">
    <!-- 标题 -->
    <div slot="header" class="clearfix">
      <span>编辑课程内容 - 课程ID：{{courseId}}</span>
    </div>
    <!-- 树形控件 allow-drop用来判断是否允许放置 -->
    <el-tree v-loading="loading" :data="treeData" :props="defaultProps"  default-expand-all draggable :allow-drop="allowDrop" @node-drop="nodeDrop">
      <!-- 自定义结构 -->
      <div class="custom-tree-node" slot-scope="{ node, data }">
        <!-- 两个span 便于使用flex布局 -->
        <span>{{ node.label }}</span>
        <span>
          <el-button
            type="text"
            size="mini"
            @click="() => edit(data)">
            编辑
          </el-button>
          <!-- 使用v-if判断当前节点是不是章节，是章节添加按钮添加课时，否则按钮位为传视频 -->
          <el-button
            type="text"
            size="mini"
            v-if="node.level === 1">
            添加课时
          </el-button>
          <el-button
            type="text"
            size="mini"
            v-else
            @click="$router.push({
              name: 'uploadVideo',
              params: {
                courseId
              },
              query: {
                lessonId: data.id
              }
            })">
            上传视频
          </el-button>
          <el-button
            type="text"
            size="mini"
            @click="() => now(node, data)">
            状态
          </el-button>
        </span>
      </div>
    </el-tree>
  </el-card>
</template>

<script>
// 引入接口 获取全部章节信息、保存或者更新章节、保存或更新课时
import { getSectionAndLesson, saveOrUpdateSection, saveOrUpdate } from '@/services/coures'
export default {
  name: 'contentManagement',
  // 参数
  props: ['courseId'],
  data () {
    return {
      // 树形控件数据
      treeData: [],
      // 树形控件节点对应关系
      defaultProps: {
        // 子节点对应名字
        children: 'lessonDTOS',
        // 节点名称对应，因为章节名和节点名不同，所以要设置两个
        label (data) {
          return data.sectionName || data.theme
        }
      },
      // 信号值，标记树形结构是都处于加载中
      loading: false
    }
  },
  // 生命周期钩子
  created () {
    // 调用方法获取课程全部章节数据
    this.getInfo(this.courseId)
  },
  methods: {
    uploadVideo (node, data) {
      console.log(node)
    },
    // 拖拽成功回调函数
    async nodeDrop (meNode, endNode, type, event) {
      // 更改信号值使树形结构处于加载中
      this.loading = true
      // 使用try-catch进行判断
      try {
        // 因为可能会包含多个节点所以可能会多次调用接口，所以使用await Promise.all接收全部调用的接口一起发送
        // 遍历要移动到的节点的父节点下的所有子节点
        await Promise.all(endNode.parent.childNodes.map((item, index) => {
          // 判断移动的是课时还是章节，课时有sectionId属性
          if (meNode.data.sectionId) {
            // 如果移动的是课时，使用课时更新接口
            return saveOrUpdate({
              id: item.data.id,
              orderNum: index
            })
          } else {
            // 如果不是课时，那就是章节，使用章节接口
            return saveOrUpdateSection({
              id: item.data.id,
              orderNum: index
            })
          }
        }))
        // 最后弹出提示
        this.$message.success('更新成功')
      } catch (err) {
        // 出现错误也弹出提示
        this.$message.error('更新失败')
      }
      // 不管成功还是失败。都要把结构加载状态取消
      this.loading = false
    },
    // 判断是否可放置方法
    // 三个参数分别是拖动的元素，要防止的元素，位置
    allowDrop (draggingNode, dropNode, type) {
      // 条件1:位置不能是inner（内部），意味着不可以放到其他节点内部
      // 条件2:两个节点有相同的父节点，，意味着只能在同一个父节点内部拖动
      return type !== 'inner' && draggingNode.parent.id === dropNode.parent.id
    },
    // 获取课程全部内容
    async getInfo (courseId) {
      // 调用接口
      const { data } = await getSectionAndLesson(courseId)
      if (data.code === '000000') {
        // 如果获取成功，把数据交给树形结构
        this.treeData = data.data
      }
    }
  }
}
</script>

<style lang="scss" scoped>
// 树形结构样式
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
